
#pragma once
#include "ShaderNode.h"

class ShaderProgram : public ShaderNode
{
public:
	enum ShaderKind
	{
		VERTEX,
		FRAGMENT,
	};

public:
	ShaderProgram(const std::string& vertexFileName, const std::string& fragmentFileName);
	virtual ~ShaderProgram() = default;

public:
	virtual bool isValid() { return getProgram() > 0; }
	virtual void release();
	virtual void use();

protected:
	void releaseShader(GLuint* shaderId);
	void initWithFileName(const std::string& vertexFileName, const std::string& fragmentFileName);
	void initWithFileSource(const std::string& vertexSource, const std::string& fragmentSource);
	bool disposeShader(const std::string& source, ShaderKind kind);
	bool verificationShader(GLuint shaderId, GLuint glStatus, const GLchar* shaderLog);

public:
	PROPERTY_READONLY(GLuint, m_program, Program);

public:
	static std::shared_ptr<ShaderProgram> create(const std::string& vertexFileName, const std::string& fragmentFileName)
	{
		auto program = std::make_shared<ShaderProgram>(vertexFileName, fragmentFileName);
		return program->isValid() ? program : nullptr;
	}
};

typedef std::shared_ptr<ShaderProgram> ShaderProgramPtr;